// Copyright (C) joyinter
// All rights reserved.
// 
// Author : Jiang Li
// Date   : 2005-5-12

#ifndef __MODCHECK_H_COMMON_GUARD__
#define __MODCHECK_H_COMMON_GUARD__

#pragma once

#include "checkbase.h"
#include "crc.h"
#include <hash_set>

namespace JoyGuard
{

//##ModelId=44C4B60D030D
class ModCheck : public CheckBase
{
public:


	//##ModelId=44C4B60D038A
    class CodeData
    {
    public:
		//##ModelId=44C4B60D038B
        DWORD   m_rva;
		//##ModelId=44C4B60D038C
        DWORD   m_size;
		//##ModelId=44C4B60D038D
        DWORD   m_hash;
    };

	//##ModelId=44C4B60D0399
    class ModData
    {
    public:
		//##ModelId=44C4B60D039A
        DWORD   m_headerHash;
		//##ModelId=44C4B60D03AB
        std::vector<BYTE> m_headerData;
		//##ModelId=44C4B60D03BB
        std::vector<CodeData> m_codeDatas;
    };

	//##ModelId=44C4B60D03BF
 	class hash_compare
	{
    public:
	    enum
        {
		    bucket_size = 4,    // 0 < bucket_size
		    min_buckets = 8,    // min_buckets = 2 ^^ N, 0 < N
        };

		//##ModelId=44C4B60D03C8
	    hash_compare()
		{
		}

		//##ModelId=44C4B60D03C9
	    size_t operator()(DWORD key) const
		{
		    return key;
		}

		//##ModelId=44C4B60D03CC
	    bool operator()(DWORD key1, DWORD key2) const
		{
		    return key1 == key2;
		}

    protected:
	};

	//##ModelId=44C4B60D03D0
    typedef stdext::hash_multimap<DWORD, ModData*> ModDataMap;
	//##ModelId=44C4B60D03D9
    typedef stdext::hash_set<BYTE*> CheckedSet;
	//##ModelId=44C4B60D03DB
    typedef std::vector<ModData*> ModDataVec;

	//##ModelId=44C4B60D031E
    CheckedSet  m_checks;
	//##ModelId=44C4B60D0323
    ModDataMap  m_datas;
	//##ModelId=44C4B60D032C
    HANDLE  m_process;
	//##ModelId=44C4B60D032D
    DWORD   m_processId;

	//##ModelId=44C4B60D032E
    virtual void OnMatch(ModData*);
	//##ModelId=44C4B60D033C
    virtual void OnCheck(void* );
	//##ModelId=44C4B60D033F
    virtual void CheckProc();
	//##ModelId=44C4B60D0341
    virtual void ReadMemory(void* dst, void* src, int len);

public:

	//##ModelId=44C4B60D034F
    ModCheck();
	//##ModelId=44C4B60D035B
    virtual ~ModCheck();

	//##ModelId=44C4B60D035D
    bool Check();
	//##ModelId=44C4B60D035E
    void LoadCheck(BYTE* check, int checkLen);

	//##ModelId=44C4B60D036B
    static bool BuildModDataFromFile(const char* fileName, ModData& modData);
	//##ModelId=44C4B60D036F
    static bool BuildModDataFromModule(HANDLE hProcess, BYTE* pMod, ModData& modData);
	//##ModelId=44C4B60D037C
    static bool BuildModDataFromMemory(BYTE* pMod, ModData& modData);
};

} // namespace JoyGuard

#endif  // __MODCHECK_H_COMMON_GUARD__
